
package com.x52im.rbchat.logic.search.viewholder;

import android.text.SpannableStringBuilder;
import android.view.View;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.eva.android.widget.WidgetUtils;
import com.eva.epc.common.util.CommonUtils;
import com.x52im.rbchat.MyApplication;
import com.x52im.rbchat.R;
import com.x52im.rbchat.cache.ImageCacheLoader;
import com.x52im.rainbowchat.http.logic.dto.GroupEntity;
import com.x52im.rainbowchat.http.logic.dto.RosterElementEntity;
import com.x52im.rainbowchat.http.logic.dto.TimeToolKit;
import com.x52im.rbchat.logic.alarm.AlarmType;
import com.x52im.rbchat.logic.alarm.model.AlarmDto;
import com.x52im.rbchat.logic.search.content.MsgSummaryContent;
import com.x52im.rbchat.logic.search.model.MsgSummaryContentDTO;

import androidx.fragment.app.Fragment;

/**
 * 消息记录（聚合搜索结果）item的viewHolder对象实现类。
 *
 * @author JackJiang
 * @since 8.2
 */
public class MsgSummaryViewHolder extends AbstractViewHolder<MsgSummaryContentDTO> {

    /** 时间显示组件 */
    protected TextView tvDateDesc;

    public MsgSummaryViewHolder(Fragment fragment, View itemView) {
        super(fragment, itemView);
        this.tvDateDesc = itemView.findViewById(R.id.search_result_item_dateView);
    }

    /**
     * 用于RecycleView的adapter中的onBindViewHolder方法。
     *
     * @param keyword    本次搜索的关键字（用于ui显示时的高亮显示）
     * @param m          列表item对应的数据对象引用
     * @param showCatlog 是否显示item上方的标题文本（true表示显示，否则不显示）
     */
    @Override
    public void onBind(String keyword, MsgSummaryContentDTO m, boolean showCatlog) {

        // 设置catlog的可见性
        itemView.findViewById(R.id.search_result_item_categoryLL).setVisibility(showCatlog?View.VISIBLE:View.GONE);
        tvCatlog.setText(showCatlog? MsgSummaryContent.CATLOG:null);

        // 查询结果只有一条时，就直接显示该消息记录内容
        if(m.getResultCount() == 1){
            tvDateDesc.setVisibility(View.VISIBLE);
            tvDateDesc.setText(TimeToolKit.getTimeStringAutoShort2(TimeToolKit.getDateTime(m.getDate()), false, false));

            String moreDesc = m.getText();
            // 高亮显示关键字
            SpannableStringBuilder ssb = WidgetUtils.coloredStringForSearch(this.fragment.getContext(), moreDesc, keyword, R.color.common_list_light_red_for_text);
            tvMoreDesc.setText(ssb != null? ssb : moreDesc);

        }
        // 否则显示一个聚合信息（可以点击查看详细的消息列表）
        else{
            tvDateDesc.setVisibility(View.GONE);
            tvDateDesc.setText(null);
            tvMoreDesc.setText(m.getResultCount()+"条相关的聊天记录");
        }

        // 通过clear()或通过Glide.with(context).load(默认占位图的资源id)两种方式都可以解决错乱问题
        Glide.with(fragment).clear(ivAvatar);// 解决方法2

        // 如果搜索结果是单聊消息
        if(m.getChatType() == MsgSummaryContentDTO.SEARCH_RESULT_CHAT_TYPE_SINGLE){

            // clear完成后设置默认占位图，确保图片显示不出现Glide导致的错位问题
            ivAvatar.setImageResource(R.drawable.default_avatar_for_contact_40dp_21pxround);

            boolean dontDiskCache = false;
            String friendUid = m.getDataId();
            String nickname = friendUid;
            // 用户的头像文件名（这个文件名目前仅用于Glide缓存图片时作为signature字段使用）
            String fileNameForUserAvatar = null;
            if (friendUid != null) {
                // 尝试从好友数据中读取对方信息
                final RosterElementEntity friendRee = MyApplication.getInstance2().getIMClientManager().getFriendsListProvider().getFriendInfoByUid2(friendUid);
                // 好友信息不为空，表示对方是好友
                if (friendRee != null) {
                    fileNameForUserAvatar = friendRee.getUserAvatarFileName();
                    nickname = friendRee.getNickNameWithRemark();

                    // 该字段为空可能是该用户没有设置头像，也可能是有可能是对方已把"我"删除，因而对方不在我
                    // 的好友列表里了，所以好友数据不存在，头像文件名也就取不到了，这种情况取头像时，就把它当陌生人聊
                    // 天模式去取头像，即dontDiskCache为true——确保相同url情况下至少app重启后能强行拉取一次最新头像
                    if (CommonUtils.isStringEmpty(fileNameForUserAvatar, true)) {
                        dontDiskCache = true;
                    }
                }
                // 对方不是好友（陌生人聊天）
                else{
                    // 因陌生人没有好友信息缓存，所以尝试从首页"消息"列表中查找缓存
                    AlarmDto d = MyApplication.getInstance2().getIMClientManager().getAlarmsProvider().getAlarmDto(AlarmType.guestChat, friendUid);
                    // 对于陌生人来说，extra1String中，存放的就是可能最新头像文件名（在查看最新用户资料时设置进来的）
                    fileNameForUserAvatar = (d != null?d.getExtraString1():null);

                    // 陌生人昵称
                    nickname = tryGetGustNickname(friendUid);

                    dontDiskCache = true;
                }

                // 加载用户头像(有头像文件名fileNameForUserAvatar作为Glide加载时的signature，可以保证在好友更改头像后，能及时加载到最新图片)
                ImageCacheLoader.loadAvatarImgWithGlide(fragment, friendUid, fileNameForUserAvatar
                        ,ivAvatar, 7 // 圆角单位是dp，（相当于xxhdpi下的21像素）
                        , R.drawable.default_avatar_for_contact_40dp_21pxround, dontDiskCache, false);
            }

            // 显示昵称
            tvName.setText(nickname);
        }
        // 如果搜索结果是群聊消息记录
        else {
            // clear完成后设置默认占位图，确保图片显示不出现Glide导致的错位问题
            ivAvatar.setImageResource(R.drawable.groupchat_groups_icon_default_r21px);

            String gid = m.getDataId();
            String gname = gid;
            if(gid != null) {
                GroupEntity ge = MyApplication.getInstance2().getIMClientManager().getGroupsProvider().getGroupInfoByGid(gid);
                if(ge != null){
                    gname = ge.getG_name();
                }

                // 加载群头像
                ImageCacheLoader.loadGroupImgWithGlide(Glide.with(fragment), gid, ivAvatar, 7 , false, R.drawable.groupchat_groups_icon_default_r21px);// 圆角单位是dp，（相当于xxhdpi下的21像素）
            }

            // 显示群名
            tvName.setText(gname);
        }
    }

    /**
     * 尝试读取了陌生人的昵称（因陌生人信息没有本地缓存，所以只能从间接渠道尝试读取）。
     *
     * @param guestUid 陌生人uid
     * @return 返回昵称字符串
     */
    public static String tryGetGustNickname(String guestUid){
        // 因陌生人没有好友信息缓存，所以尝试从首页"消息"列表中查找缓存
        AlarmDto d = MyApplication.getInstance2().getIMClientManager().getAlarmsProvider().getAlarmDto(AlarmType.guestChat, guestUid);
        // 陌生人昵称
       return (d != null? d.getTitle() : "陌生人（UID: "+guestUid+"）");
    }
}
